package com.twohand.admin.Service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.twohand.admin.Dto.*;
import com.twohand.admin.Entity.User;
import com.twohand.admin.Entity.UserRole;
import com.twohand.admin.Mapper.UserMapper;
import com.twohand.admin.Service.MenuService;
import com.twohand.admin.Service.UserRoleService;
import com.twohand.admin.Service.UserService;
import com.twohand.admin.Util.Encode;
import com.twohand.admin.Util.FileUpload;
import com.twohand.admin.Util.JwtUtil;
import com.twohand.admin.Util.PageResponse;
import com.twohand.admin.Vo.UserListVo;
import com.twohand.admin.Vo.UserVo;
import com.twohand.utils.Response.BaseException;
import com.twohand.utils.Response.HttpRequest;
import org.bouncycastle.jcajce.provider.asymmetric.rsa.DigestSignatureSpi;
import org.bouncycastle.jcajce.provider.digest.SHA256;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;
    @Autowired
    MenuService menuService;
    @Autowired
    UserRoleService userRoleService;
    @Autowired
    FileUpload fileUpload;
    @Value("${custom.defaultPwd}")
    String defaultPwd;
    Logger log = LoggerFactory.getLogger(UserServiceImpl.class);
//    @Autowired
//    RedisCache redisCache;
    @Override
    public PageResponse<UserListVo> getAllUser(UserListQueryDto userListQueryDto) {
        PageHelper.startPage(userListQueryDto.getPageNum(),userListQueryDto.getPageSize());
        List<UserListVo> userListVos = userMapper.queryAll(userListQueryDto.getNickname(),userListQueryDto.getOpenid(),userListQueryDto.getRoleId());
        PageInfo<UserListVo> pageInfo = new PageInfo<>(userListVos);
        return new PageResponse<UserListVo>(pageInfo,userListVos);
    }

    @Override
    public User getUserById(Integer id) {
        return userMapper.selectById(id);
    }

    @Override
    public Boolean insertUser(AddUserDto addUserDto) {
        User user = new User();
        user.setNickname(addUserDto.getNickname());
        user.setAvatarUrl(addUserDto.getAvatarUrl());
        user.setPwd(addUserDto.getPwd());
        user.setSid(addUserDto.getSid());
        Boolean aBoolean = userMapper.insert(user) > 0;
        if(aBoolean){
            //用户表插入成功，向关联表插入数据
            Integer roleId = addUserDto.getRoleId();
            Integer userId = user.getId();
            return userMapper.insertUserAndRole(userId,roleId) > 0;
        }
        return userMapper.insert(user) > 0;
    }

    @Override
    public Boolean updateUser(ModifyUserDto modifyUserDto) {
        User user = new User();
        user.setNickname(modifyUserDto.getNickname());
        user.setAvatarUrl(modifyUserDto.getAvatarUrl());
        user.setId(modifyUserDto.getId());
        user.setSid(modifyUserDto.getSid());
        //先更新用户角色
        if(userMapper.updateById(user) > 0){
            //更新user_role表 -- roleId
            UserRole userRole = new UserRole();
            userRole.setRoleId(modifyUserDto.getRoleId());
            return userRoleService.updateByUserId(userRole,user.getId());

        }
        return false;
    }

    @Override
    public Boolean deleteUserById(Integer id) {
        //先删除user_role表中 user_id == id的  不存在也行
        userRoleService.deleteByUserId(id);
        //
        return userMapper.deleteById(id) > 0;
    }

    @Override
    public MiniLoginRes miniprogramLogin(String code) throws JsonProcessingException {
        throw new BaseException(500,"未知错误");
    }

    @Override
    public Object adminLogin(String username,String password) throws NoSuchAlgorithmException {
        User user = userMapper.selectByUserAPass(username,Encode.Sha256(password));

        if(user == null){
            throw new BaseException(403,"用户名或密码错误");
        }
        userMapper.updateLoginTime(user.getId(), LocalDateTime.now());
        UserVo userVo = new UserVo();
        userVo.setId(user.getId());
        userVo.setNickname(user.getNickname());
        userVo.setRoleId(userRoleService.getRoleByUserId(user.getId()));
        userVo.setCreateTime(user.getCreateTime());
        userVo.setUpdateTime(user.getUpdateTime());
        HashMap hashMap = new HashMap();
        hashMap.put("userinfo",user);
        String token = JwtUtil.getToken(user);
//        redisCache.setCacheObject(token,user,30, TimeUnit.MINUTES);
        hashMap.put("token",token);
        hashMap.put("router",menuService.getUserMenuList(user.getId()));
        //带上权限消息
        hashMap.put("permission",menuService.getPermissionByUserId(user.getId()));
        return hashMap;
    }

    @Override
    public Object uploadAvatar(MultipartFile multipartFile) {
        return fileUpload.uploadImage(multipartFile);
    }

    @Override
    public Boolean changPassword(ChangePwdDto changePwdDto) {
        String oldPwd = changePwdDto.getOldPwd();
        String newPwd = changePwdDto.getNewPwd();
        String confirmPwd = changePwdDto.getConfirmPwd();
        if(!newPwd.equals(confirmPwd)){
            throw new BaseException(500,"两次密码不一致，请修改");
        }
        //获取当前用户
        User tokenUser = JwtUtil.getCurrentUser();
        //根据用户id获取实体
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",tokenUser.getId());
        User user = userMapper.selectOne(queryWrapper);
        if(user==null){
            throw new BaseException(500,"用户不存在");
        }
        try{
            String userPwdSha256 = user.getPwd();
            String newPwdSha = Encode.Sha256(newPwd);
            String oldPwdSha = Encode.Sha256(oldPwd);
            if(!oldPwdSha.equals(userPwdSha256)){
                throw new BaseException(500,"修改失败,密码错误");
            }
            user.setPwd(newPwdSha);
            userMapper.updateById(user);
            return true;
        }catch (Exception e){
            throw new BaseException(500,e.getMessage());
        }
    }

    @Override
    public Boolean resetPwd(Integer id) throws NoSuchAlgorithmException {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",id);
        User user = userMapper.selectOne(queryWrapper);
        user.setPwd(Encode.Sha256(defaultPwd));
        return userMapper.updateById(user) > 0;
    }

}
